﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using TileEngine.tiles.material;
using TileEngine.liquids;
using TileEngine.items.pickaxes;
using TileEngine.items;
using TileEngine.tiles;
using TileEngine.items.tiles.material;

namespace TileEngine
{
    class World
    {
        public Vector2 Gravity;
        public Map tiles;
        public Player player;
        public Background background;
        public LiquidEngine liquidEngine;
        public List<Iitem> items;
        public int gameTime=200000;
        public int gameTimeHold=0;
        int liquidUpdateTime = 0;

        public List<PopupText> PopupTexts;

        bool tabFlag = false;
        public World()
        {
            Global.currentWorld = this;
            Gravity = new Vector2(0, 0.00008f);
            tiles = new Map(1000,1000);
            WorldCreator.Create(tiles);
            player =  new Player(this);
            background = new Background();
            liquidEngine = new LiquidEngine(this);
            player.inventory.addItem(new Pickaxe(new Vector2(0,0)));
            player.inventory.addItem(new Pickaxe(new Vector2(0,0)));
            
            for (int i = 0; i < 80; i++)
            {
                player.inventory.addItem(new TorchItem(new Vector2(0, 0)));
                player.inventory.addItem(new DirtItem(new Vector2(0, 0)));
                player.inventory.addItem(new GoldItem(new Vector2(0, 0)));
                player.inventory.addItem(new AdamentineItem(new Vector2(0, 0)));
                player.inventory.addItem(new BoronItem(new Vector2(0, 0)));
                player.inventory.addItem(new MithrilItem(new Vector2(0, 0)));
                player.inventory.addItem(new StoneItem(new Vector2(0, 0)));
                player.inventory.addItem(new NikelItem(new Vector2(0, 0)));
                player.inventory.addItem(new CoalItem(new Vector2(0, 0)));
                player.inventory.addItem(new CromeItem(new Vector2(0, 0)));
            }
            items = new List<Iitem>();
            PopupTexts = new List<PopupText>();

        }

        public void draw(SpriteBatch spriteBatch,GameTime gameTime)
        {

            Vector2 firstSquare = new Vector2(Camera.Location.X / Global.tileSize.X, Camera.Location.Y / Global.tileSize.Y);
            int firstX = (int)firstSquare.X;
            int firstY = (int)firstSquare.Y;

            Vector2 squareOffset = new Vector2(Camera.Location.X % Global.tileSize.X, Camera.Location.Y % Global.tileSize.Y);
            int offsetX = (int)squareOffset.X;
            int offsetY = (int)squareOffset.Y;
                LightEngine.calculateLights(new Point(firstX - LightEngine.margin, firstY - LightEngine.margin), new Point(firstX + LightEngine.margin + (int)Camera.tilesOnScreen.X, firstY + LightEngine.margin + (int)Camera.tilesOnScreen.Y));
            background.draw(spriteBatch);
            
            tiles.draw(spriteBatch,firstX,firstY,offsetX,offsetY);
            player.draw(spriteBatch, gameTime,LightEngine.getColor((int)Camera.tilesOnScreen.X/2,(int)Camera.tilesOnScreen.Y/2));
            player.inventory.draw(spriteBatch);

            for (int i = 0; i < items.Count; i++)
            {
                if(items[i].getLocation().X>Camera.Location.X && items[i].getLocation().Y>Camera.Location.Y &&
                    items[i].getLocation().X<Camera.Location.X+Camera.screenDimension.X && items[i].getLocation().Y<Camera.Location.Y+Camera.screenDimension.Y)
                items[i].draw(spriteBatch,LightEngine.getColor((int)items[i].getLocation().X/Global.tileSize.X-firstX,(int)items[i].getLocation().Y/Global.tileSize.Y-firstY));
            }
            for (int i = 0; i < PopupTexts.Count; i++)
            {
                PopupTexts[i].draw(spriteBatch);
            }
        }
        public void update(GameTime gameTime, KeyboardState keys)
        {
            liquidUpdateTime += gameTime.ElapsedGameTime.Milliseconds;
            if (liquidUpdateTime > 60)
            {
                liquidUpdateTime -= 60;
                liquidEngine.update();
            }


            this.gameTime+=gameTime.ElapsedGameTime.Milliseconds;
            
            updateItems(gameTime);
            if (keys.IsKeyDown(Keys.Tab) && !tabFlag)
            {
                player.save();
                player.inventory.findAvailableRecipes();
                //PopupTexts.Add(new PopupText(new Color(200, 0, 0, 255), Global.myRandom.Next(-100, 100).ToString(), new Vector2(Mouse.GetState().X, Mouse.GetState().Y)));
                tabFlag = true;
                player.inventory.isShown = !player.inventory.isShown;
            }
            if (keys.IsKeyUp(Keys.Tab) && tabFlag)
                tabFlag = false;

            if (!player.inventory.isShown)
            {
                if (Mouse.GetState().RightButton == ButtonState.Pressed)
                {
                    Water newWater = new Water();
                    if (tiles[(Mouse.GetState().X + (int)Camera.Location.X) / Global.tileSize.X, (Mouse.GetState().Y + (int)Camera.Location.Y) / Global.tileSize.Y].liquid == null)
                    {
                        liquidEngine.dynamicLiquids.Add(new Vector2((Mouse.GetState().X + (int)Camera.Location.X) / Global.tileSize.X, (Mouse.GetState().Y + (int)Camera.Location.Y) / Global.tileSize.Y));
                        tiles[(Mouse.GetState().X + (int)Camera.Location.X) / Global.tileSize.X, (Mouse.GetState().Y + (int)Camera.Location.Y) / Global.tileSize.Y].liquid = newWater;
                    }

                    //tiles[(Mouse.GetState().X + (int)Camera.Location.X) / 20, (Mouse.GetState().Y + (int)Camera.Location.Y) / 20].tile =
                    //    new Dirt((Mouse.GetState().X + (int)Camera.Location.X) / 20, (Mouse.GetState().Y + (int)Camera.Location.Y) / 20);
                }
            }


            player.update(gameTime, keys);
            player.inventory.update(gameTime, keys);
            background.update();
            //if(sonrasil%30==29)
            
        }

        public void updateItems(GameTime gameTime)
        {
            for (int i = 0; i < items.Count; i++)
            {
                items[i].update(gameTime);
            }
            if (items.Count > Global.maxItemCount)
            {
                items.RemoveAt(0);
            }
        }
        public static bool isMovePossible(Rectangle start)
        {
            for (int i = (int)Math.Floor((float)(start.Left) / Global.tileSize.X); i < (int)Math.Ceiling((float)(start.Right) / Global.tileSize.Y); i++)
            {
                for (int j = (int)Math.Floor((float)(start.Top) / Global.tileSize.Y); j < (int)Math.Ceiling((float)(start.Bottom) / Global.tileSize.Y); j++)
                    if (Global.currentWorld.tiles[i, j].tile.GetType() != typeof(Empty))

                        return false;
            }
            return true;
        }
    }
}
